/*
 * @Author: Clark
 * @Email: haixuanwoTxh@gmail.com
 * @Date: 2023-01-28 16:24:34
 * @LastEditors: Clark
 * @LastEditTime: 2023-01-28 16:29:51
 * @Description: file content
 */

#include <limits.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>

#define MAXSTRINGSZ 4096

static pthread_key_t key;
static pthread_once_t init_done = PTHREAD_ONCE_INIT;
pthread_mutex_t env_mutex = PTHREAD_MUTEX_INITIALIZER;
extern char **environ;

static void thread_init(void)
{
    pthread_key_create(&key, free);
}

char *getenv(const char *name)
{
    pthread_once(&init_done, thread_init);
    pthread_mutex_lock(&env_mutex);

    char *envbuf = (char *)pthread_getspecific(key);
    if (NULL == envbuf)
    {
        envbuf = malloc(MAXSTRINGSZ);
        if (NULL == envbuf)
        {
            pthread_mutex_unlock(&env_mutex);
            return NULL;
        }
        pthread_setspecific(key, envbuf);
    }

    int len = strlen(name);
    for (size_t i = 0; NULL != environ[i]; i++)
    {
        if ((0 == strncmp(name, environ[i], len)) && ('=' == environ[i][len]))
        {
            strncpy(envbuf, &environ[i][len+1], MAXSTRINGSZ -1);
            pthread_mutex_unlock(&env_mutex);
            return envbuf;
        }
    }

    pthread_mutex_unlock(&env_mutex);
    return NULL;
}
